package org.liaohailong.victor;

import org.junit.Test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest2 {

    @Test
    public void canJump() {
////        int[] arr = {2, 3, 1, 1, 4}; // true
//        int[] arr = {3, 2, 1, 0, 4}; // false
//        boolean result = new DPStudy().canJump(arr);
//        log("result = " + result);

//        int[] arr = {2, 3, 1, 1, 4};
        int[] arr = {2, 3, 0, 1, 4};
        int jump = new DPStudy().jump(arr);
        log("jump = " + jump);
    }


    @Test
    public void uniquePaths() {
//        int m = 3, n = 2; // 3
//        int m = 3, n = 7; // 28
        int m = 51, n = 9; // 28
        long cost = calc(() -> {
            int count = new DPStudy().uniquePaths(m, n);
            log("count = " + count);
        });
        log("cost = " + cost + "ms");
    }

    @Test
    public void coinChange() {
//        int[] coins = {1, 2, 5};
//        int amount = 11;

//        int[] coins = { 2};
//        int amount = 3;

//        int[] coins = {1};
//        int amount = 0;

        int[] coins = {186, 419, 83, 408};
        int amount = 6249;

        int count = new DPStudy().coinChange(coins, amount);
        log("count = " + count);
    }

    @Test
    public void lengthOfLIS() {
//        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18}; // 4
//        int[] nums = {0,1,0,3,2,3}; // 4
//        int[] nums = {7,7,7,7,7,7,7}; // 1
        int[] nums = {4, 10, 4, 3, 8, 9}; // 3
        int count = new DPStudy().lengthOfLIS(nums);
        log("count = " + count);
    }

    @Test
    public void isHappy() {
//        int n = 19;
        int n = 2;
        boolean happy = new MathStudy().isHappy(n);
        log("happy = " + happy);
    }

    @Test
    public void trailingZeroes() {
        int n = 13;
        int val = new MathStudy().trailingZeroes(n);
        log("val = " + val);
    }

    @Test
    public void deleteAndEarn() {
        int[] nums = {3, 4, 2};
        int count = new DPStudy().deleteAndEarn(nums);
        log("count = " + count);
    }


    @Test
    public void test() {
        int[] arr = new int[1000000];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr.length * 3 / 4 - i;
        }
        // 原数组
        log(arr);

        // 乱序
        shuffle(arr);
        log(arr);

        // 移除负数 On
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i : arr) linkedList.addLast(i);

        Iterator<Integer> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            if (next < 0) iterator.remove();
        }

        log(linkedList);
    }

    @Test
    public void mySqrt() {
//        int x = 4; // 2
//        int x = 8; // 2
//        int x = 10; // 3
//        int x = 0; // 0
//        int x = 1; // 1
//        int x = 2; // 1
//        int x = 6; // 2
        int[] arr = {0, 1, 2, 4, 6, 8, 10};
        for (int i : arr) {
            int j = new MathStudy().mySqrt(i);
            log("i = " + i + ", j = " + j);
        }
    }

    @Test
    public void getSum() {
        int a = 2;
        int b = 3;
        int sum = new OtherStudy().getSum(a, b);
        log("sum = " + sum);
    }

    private void shuffle(int[] arr) {
        int low = 0;
        int mid = arr.length / 2;
        int high = arr.length - 1;

        while (low < mid) {
            if (low % 2 == 0) {
                // 偶数，从前面取
                swap(arr, low, mid + low);
            } else {
                // 奇数，从后面取
                swap(arr, low, high - low);
            }
            low++;
        }
    }

    private void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }


    private void log(int[] arr) {
        if (arr.length > 100) {
            int[] shorter = new int[100];
            System.arraycopy(arr, 0, shorter, 0, 100);
            arr = shorter;
        }
        log(Arrays.toString(arr));
    }

    private void log(LinkedList<Integer> list) {
        int count = Math.min(100, list.size());

        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            sb.append(next);
            count--;
            if (count <= 0) break;
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("]");
        log(sb.toString());
    }

    private void log(String msg, Object... args) {
        String format = String.format(msg, args);
        System.out.println(format);
    }

    private long calc(Runnable runnable) {
        long startMs = System.currentTimeMillis();
        runnable.run();
        return System.currentTimeMillis() - startMs;
    }
}